package xml;

import java.io.*;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Text;

import com.sun.org.apache.xml.internal.serialize.OutputFormat;
import com.sun.org.apache.xml.internal.serialize.XMLSerializer;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Set;

import java.util.Vector;
import org.w3c.dom.CDATASection;
import org.w3c.dom.NodeList;

/**
 * 
 * @author Randy van Heijst
 */
public class DOMBuilder {
	Document dom;
	DocumentBuilderFactory dbf;
    private HashMap<String, Vector> hm;

    /**
     * Zet de door de client aangeleverde informatie om naar een XML file
     *
     * @param address Het adres van de cliënt waar de te maken XML file bij hoort
     * @param hm Hashmap met daarin de afdelingen met een vector van bijbehorende opleidingen
     */
	public void createClientXML(String address, HashMap hm) {
		this.hm = hm;
        createDocument();
        createDOMTree();
		printClientXML(address);
	}

    /**
     * Maakt de main XML file met alle afdelingen en opleidingen
     *
     * @param hm Hashmap met daarin de afdelingen met een vector van bijbehorende opleidingen
     */
    public void createMainXML(HashMap hm) {
        this.hm = hm;
        createDocument();
        createDOMTree();
        printMainXML();
    }

	/**
	 * Using JAXP in implementation independent manner create a document object
	 * using which we create a xml tree in memory
	 */
	private void createDocument() {

		//get an instance of factory
		dbf = DocumentBuilderFactory.newInstance();
		try {
		//get an instance of builder
		DocumentBuilder db = dbf.newDocumentBuilder();

		//create an instance of DOM
		dom = db.newDocument();

		}catch(ParserConfigurationException pce) {
			//dump it
			System.out.println("Error while trying to instantiate DocumentBuilder " + pce);
			System.exit(1);
		}

	}

	/**
	 * Het aanmaken van de XML structuur
	 */
	public void createDOMTree(){
		Element rootEle = dom.createElement("HHS");
		dom.appendChild(rootEle);
        
        Set namenset = hm.keySet();
		Iterator it = namenset.iterator();
		while (it.hasNext()) {
            String s = it.next().toString();
			rootEle.appendChild(createAfdelingElement(s,hm.get(s)));
		}
    }

    /**
     * Maakt een Element van de meegegeven afdeling
     *
     * @param afdNaam Naam van de meegegeven afdeling
     * @param oplNaam Vector met alle geselecteerde opleidingen die bij deze afdeling horen
     * @return Element van afdeling met daarin alle Elementen van de geselecteerde opleiding(en)
     */
    public Element createAfdelingElement(String afdNaam, Vector oplNaam) {
        Element afdeling = dom.createElement("afdeling");
        afdeling.setAttribute("naam", afdNaam);
        
        for(int i = 0; i < oplNaam.size(); i++) {
            afdeling.appendChild(createOpleidingElement(afdNaam, oplNaam.get(i).toString()));
        }

        return afdeling;
    }

    /**
     * Maakt een Element van de meegegeven opleiding
     *
     * @param afdNaam De naam van de afdeling waar de opleiding onder valt
     * @param oplNaam De naam van de opleiding die naar een nieuwe Element moet worden omgezet
     * @return Element van een opleiding
     */
    public Element createOpleidingElement(String afdNaam, String oplNaam) {
        Document doc = null;
        Element opleiding = null;


        try {
            File file = new File("afdelingen/" + afdNaam + "/" + oplNaam + ".xml");
            
            if (file.exists()) {
                
                DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
                DocumentBuilder builder = factory.newDocumentBuilder();
                doc = builder.parse(file);
                doc.getDocumentElement().normalize();
                NodeList list = doc.getElementsByTagName("*");

                Text naamText = dom.createTextNode(list.item(1).getTextContent());
                Text locatieText = dom.createTextNode(list.item(2).getTextContent());
                CDATASection infoText = dom.createCDATASection(list.item(3).getTextContent());

                opleiding = dom.createElement("opleiding");
                Element naam = dom.createElement("naam");
                Element locatie = dom.createElement("locatie");
                Element info = dom.createElement("info");

                naam.appendChild(naamText);
                locatie.appendChild(locatieText);
                info.appendChild(infoText);

                opleiding.appendChild(naam);
                opleiding.appendChild(locatie);
                opleiding.appendChild(info);

            }
        } catch (Exception e) {
            System.out.println(e);
        }
        return opleiding;
    }


	/**
     * De gemaakte document wordt naar een XML file weggeschreven
     *
     * @param address Het adres van de client waar de te maken XML file bij hoort
     */
	private void printClientXML(String address){
		try
		{
			OutputFormat format = new OutputFormat(dom);
			format.setIndenting(true);

			XMLSerializer serializer = new XMLSerializer(
			new FileOutputStream(new File(address+".xml")), format);

			serializer.serialize(dom);

		} catch(IOException ie) {
		    ie.printStackTrace();
		}
	}

    /**
     * Het aanmaken van de main XML file die in de jar wordt meegestuurd
     */
    private void printMainXML() {
        try
		{
			OutputFormat format = new OutputFormat(dom);
			format.setIndenting(true);

			XMLSerializer serializer = new XMLSerializer(
			new FileOutputStream(new File("jarFiles/HHS.xml")), format);

			serializer.serialize(dom);

		} catch(IOException ie) {
		    ie.printStackTrace();
		}
    }
}